package psd.model.Prolog.Converters;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SuperFieldAccess;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;

import psd.model.IConverter;
import psd.model.Prolog.FactGenerationToolbox;
import psd.model.Prolog.PrologConverter;


public class PrologSimpleNameConverter extends PrologConverter implements
IConverter<SimpleName>{

	public PrologSimpleNameConverter(FactGenerationToolbox toolbox) {
		super(toolbox);
	}

	@Override
	public boolean convert(SimpleName node) {
		 if(node.getParent() instanceof AbstractTypeDeclaration)
	        {
	            return false;
	        }
	        if(node.getParent() instanceof Annotation)
	        {
	            return false;
	        }
	        if(node.getParent().getNodeType() == 30 || node.getParent().getNodeType() == 18 || node.getParent().getNodeType() == 52 || node.getParent().getNodeType() == 10 || node.getParent().getNodeType() == 31 || node.getParent().getNodeType() == 80)
	        {
	            return false;
	        }
	        generatePackageFactIfNecessary(node.resolveBinding());
	        if(node.resolveBinding() == null)
	        {
	            ASTNode nodeparent = node.getParent();
	            if(nodeparent.getNodeType() == 32 && CALLT_THAT_NEED_IDENT.contains(nodeparent))
	            {
	                String args[] = {
	                    quote(node.getIdentifier()), idResolver.getID(node.resolveBinding())
	                };
	                createBodyFact(node, "identT", args);
	                writeSourceLocationArgumentIdentifier(node, node);
	            }
	            return false;
	        }
	        if(node.resolveBinding().getKind() == 2)
	        {
	            if(((ITypeBinding)node.resolveBinding()).isTypeVariable())
	            {
	                return false;
	            } else
	            {
	                handleSelectsIdents(node, null);
	                return false;
	            }
	        }
	        if(node.resolveBinding().getKind() == 3)
	        {
	            IVariableBinding vb = (IVariableBinding)node.resolveBinding();
	            if(!vb.isField())
	            {
	                if((node.getParent().getParent().getNodeType() == 60 || node.getParent().getParent().getNodeType() == 58) && ((VariableDeclarationFragment)node.getParent()).getName() == node)
	                {
	                    return false;
	                }
	                String args[] = {
	                    quote(node.getIdentifier()), idResolver.getID(node.resolveBinding())
	                };
	                createBodyFact(node, "identT", args);
	                writeSourceLocationArgumentIdentifier(node, node);
	            } else
	            {
	                if(node.getParent().getNodeType() == 22 && ((FieldAccess)node.getParent()).getName() == node)
	                {
	                    return false;
	                }
	                if(node.getParent().getNodeType() == 47 && ((SuperFieldAccess)node.getParent()).getName() == node)
	                {
	                    return false;
	                }
	                if(node.getParent().getParent().getNodeType() == 23 && ((VariableDeclarationFragment)node.getParent()).getName() == node)
	                {
	                    return false;
	                }
	                generateGetFieldIfNodeIsFieldAccess(node, node.getIdentifier());
	            }
	        }
	        return false;
	}
	
	 private boolean generateGetFieldIfNodeIsFieldAccess(Name node, String name)
	    {
	        if(node.resolveBinding() == null)
	        {
	            return false;
	        }
	        if(node.resolveBinding().getKind() == 3 && ((IVariableBinding)node.resolveBinding()).isField())
	        {
	            String args[] = {
	                node.isSimpleName() ? quote("null") : idResolver.getID(((QualifiedName)node).getQualifier()), quote(name), idResolver.getID(node.resolveBinding())
	            };
	            createBodyFact(node, "getFieldT", args);
	            writeSourceLocationArgumentIdentifier(node, node);
	            if(!node.isSimpleName())
	            {
	                Name q = ((QualifiedName)node).getQualifier();
	                String atomName;
	                if(q.isSimpleName())
	                {
	                    atomName = ((SimpleName)q).getIdentifier();
	                } else
	                {
	                    atomName = ((QualifiedName)q).getName().getIdentifier();
	                }
	                if(!generateGetFieldIfNodeIsFieldAccess(q, atomName))
	                {
	                    handleSelectsIdents(q, null);
	                }
	            }
	            return true;
	        } else
	        {
	            return false;
	        }
	    }


}
